package com.sfeir.client.activity;

import java.util.List;
import java.util.Map;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.CanvasGradient;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.web.bindery.event.shared.EventBus;
import com.sfeir.canvas.activities.client.AbstractCanvasActivity;
import com.sfeir.canvas.activities.client.event.PageChangeEvent;
import com.sfeir.canvas.util.client.ResourceManager;
import com.sfeir.canvas.util.client.event.AllResourcesLoadedEvent;
import com.sfeir.canvas.util.client.event.AllResourcesLoadedHandler;
import com.sfeir.canvas.util.client.event.ResourceLoadedEvent;
import com.sfeir.canvas.util.client.event.ResourceLoadedHandler;
import com.sfeir.client.i18n.TetrisConstants;
import com.sfeir.client.service.AppServiceAsync;
import com.sfeir.client.util.Constants;
import com.sfeir.shared.Level;

public class LoadingActivity extends AbstractCanvasActivity {

	private final ResourceManager manager;
	private final TetrisConstants texts;
	private EventBus bus;
	private boolean resourcesLoaded;
	private boolean levelsLoaded;
	private boolean scoresLoaded;
	private final AppServiceAsync service;
	private float percent;
	private boolean isDisplayed;
	

	public LoadingActivity(ResourceManager manager, AppServiceAsync service) {
		this.manager = manager;
		this.service = service;
		this.isDisplayed = false;
		this.texts = GWT.create(TetrisConstants.class);
	}

	@Override
	public void start(Canvas canvas, EventBus bus) {
		final Context2d ctx = canvas.getContext2d();
		this.isDisplayed = true;
		this.percent = -1;
		this.resourcesLoaded = false;
		this.levelsLoaded = false;
		this.scoresLoaded = false;
		this.bus = bus;
		ctx.setFillStyle("black");
		ctx.fillRect(0, 0, Constants.CANVAS_WIDTH, Constants.CANVAS_HEIGHT);
		ctx.setFillStyle("white");
		ctx.setFont("bold 50px calibri");
		ctx.fillText(texts.loading(), 270, 300);
		ctx.setFont("normal 14px calibri");
		ctx.fillText(texts.stupidFact(), 50, 550);
		ctx.setStrokeStyle("white");
		ctx.strokeRect(100, 400, 600, 50);
		this.service.getLevels(new AsyncCallback<List<Level>>() {
			@Override
			public void onSuccess(List<Level> result) {
				levelsLoaded = true;
				fireEventIfNeeded();
			}
			
			@Override
			public void onFailure(Throwable caught) {
				levelsLoaded = true;
				fireEventIfNeeded();
			}
		});
		service.getUserLevels(new AsyncCallback<List<Map<String,Object>>>() {
			@Override
			public void onFailure(Throwable caught) {
				scoresLoaded = true;
				fireEventIfNeeded();
			}

			@Override
			public void onSuccess(List<Map<String, Object>> result) {
				scoresLoaded = true;
				fireEventIfNeeded();
			}
		});
		
		bus.addHandler(AllResourcesLoadedEvent.TYPE, new AllResourcesLoadedHandler() {
			@Override
			public void onAllResourcesLoaded(AllResourcesLoadedEvent event) {
				resourcesLoaded = true;
				fireEventIfNeeded();
			}
		});
		bus.addHandler(ResourceLoadedEvent.TYPE, new ResourceLoadedHandler() {
			@Override
			public void onResourcesLoaded(ResourceLoadedEvent event) {
				if(event.getPercentage() > percent) {
					percent = event.getPercentage();
					paintPercentage(ctx);
				}
			}
		});
		this.manager.preloadResources();
	}

	@Override
	public void stop() {
		this.isDisplayed = false;
	}

	private void fireEventIfNeeded() {
		if(levelsLoaded && scoresLoaded && resourcesLoaded) {
			bus.fireEvent(new PageChangeEvent(PageChangeEvent.NEXT, null));
		}
	}
	
	private void paintPercentage(Context2d ctx) {
		if(!this.isDisplayed) {
			return ;
		}
		ctx.save();
		ctx.setFillStyle("black");
		ctx.fillRect(102, 402, 596, 46);
		CanvasGradient gradient = ctx.createLinearGradient(0, 0, 598, 56);
		gradient.addColorStop(0, "white");
		gradient.addColorStop(0.5, "yellow");
		gradient.addColorStop(1, "red");
		ctx.setFillStyle(gradient);
		ctx.fillRect(102, 402, 596 * percent, 46);
		ctx.restore();
	}
}
